import { EventEmitter } from 'events'
import TRTCCloud, { Rect, TRTCAppScene, TRTCBeautyStyle, TRTCParams, TRTCRoleType, TRTCVideoEncParam, TRTCVideoResolution } from 'trtc-electron-sdk'

interface ImLoginParam {
  /** 用户 ID */
  userId: string
  /**  签名 */
  userSig: string
}

interface EnterRoomParams {
  /** 教室id */
  classId: number
  /** 昵称 */
  nickName?: string
  /** 头像地址 */
  avatar?: string
}
interface RemoteParams {
  /** 用户id */
  userId: string
  /** 画面类型,1-大画面，2-小画面，3-屏幕分享 */
  streamType: number
  /** 承载显示画面的 DOM */
  view: HTMLElement
}
interface StopRemoteParams {
  /** 用户id */
  userId: string
  /** 画面类型,1-大画面，2-小画面，3-屏幕分享 */
  streamType: number
}
interface BeautyParams {
  /** 1表示光滑，适用于美女秀场，效果比较明显，2表示自然，磨皮算法更多地保留了面部细节，主观感受上会更加自然 */
  beautyStyle: number
  /** 美颜级别，取值范围0 - 9，0表示关闭，1 - 9值越大，效果越明显 */
  beauty: number
  /** 美白级别，取值范围0 - 9，0表示关闭，1 - 9值越大，效果越明显 */
  white: number
  /** 红润级别，取值范围0 - 9，0表示关闭，1 - 9值越大，效果越明显，该参数 windows 平台暂未生效 */
  ruddiness: number
}

interface CreateRoomParams {
  /** 教室id */
  classId: number
  /** 昵称 */
  nickName: string
  /** 头像地址 */
  avatar?: string
  /** 群组类型 */
  timType?: string
}

interface ProfileParams {
  /** 昵称 */
  nickName: string
  /** 头像地址 */
  avatar?: string
}

interface MessageParams {
  /** 教室id */
  classId: number
  /** 消息文本 */
  message: string
}

interface SourceParam {
  /** 采集源类型 */
  type: number
  /** 采集源ID，对于窗口，该字段指示窗口句柄；对于屏幕，该字段指示屏幕ID */
  sourceId: string
  /** 采集源名称，UTF8编码 */
  sourceName: string
}

export const ENUM_EVENT = {
  /** 本地进房成功 */
  ENTER_ROOM_SUCCESS: 'ENTER_ROOM_SUCCESS',
  /** 本地退房 */
  LEAVE_ROOM_SUCCESS: 'LEAVE_ROOM_SUCCESS',
  /** 老师进入房间，开始上课 */
  TEACHER_ENTER: 'TEACHER_ENTER',
  /** 老师离开房间，结束上课 */
  TEACHER_LEAVE: 'TEACHER_LEAVE',
  /** 学生加入房间 */
  STUDENT_ENTER: 'STUDENT_ENTER',
  /** 学生离开房间 */
  STUDENT_LEAVE: 'STUDENT_LEAVE',
  /** 开启屏幕分享 */
  SCREEN_SHARE_ADD: 'SCREEN_SHARE_ADD',
  /** 关闭屏幕分享 */
  SCREEN_SHARE_REMOVE: 'SCREEN_SHARE_REMOVE',
  /** 远端视频流添加事件，当远端用户发布视频流后会收到该通知 */
  REMOTE_VIDEO_ADD: 'REMOTE_VIDEO_ADD',
  /** 远端视频流移出事件，当远端用户取消发布视频流后会收到该通知 */
  REMOTE_VIDEO_REMOVE: 'REMOTE_VIDEO_REMOVE',
  /** 用户开启音频上行 */
  REMOTE_AUDIO_ADD: 'REMOTE_AUDIO_ADD',
  /** 用户没有开启音频上行 */
  REMOTE_AUDIO_REMOVE: 'REMOTE_AUDIO_REMOVE',
  /** 教室被销毁 */
  ROOM_DESTROYED: 'ROOM_DESTROYED',
  /** 收到IM 消息 */
  MESSAGE_RECEIVED: 'MESSAGE_RECEIVED',
  /** 被踢下线 */
  KICKED_OUT: 'KICKED_OUT',
  /** 异常 */
  ERROR: 'ERROR',
  /** 警告 */
  WARNING: 'WARNING',
  /** 开始问答时间 */
  QUESTION_TIME_STARTED: 'QUESTION_TIME_STARTED',
  /** 结束问答 */
  QUESTION_TIME_STOPPED: 'QUESTION_TIME_STOPPED',
  /** 学生举手 */
  STUDENT_RAISE_HAND: 'STUDENT_RAISE_HAND',
  /** 被邀请回答问题、点名 */
  BE_INVITED_TO_PLATFORM: 'BE_INVITED_TO_PLATFORM',
  /** 结束回答 */
  ANSWERING_FINISHED: 'ANSWERING_FINISHED'
}

interface ScreenShareType {
  iconBGRA: { width: number; height: number; length: number; buffer: ArrayBuffer }
  isMinimizeWindow: false
  sourceId: string
  sourceName: string
  thumbBGRA: { width: number; height: number; length: number; buffer: ArrayBuffer }
  type: number
}

interface ConfigOption {
  /** 应用id trtc管理后台 获取 */
  appId: number
  /** 用户id，在房间内的唯一标识 */
  userId: string
  /** 签名，用户鉴权使用 */
  userSig: string
}

export default class SrtcClient extends EventEmitter {
  private appId: number
  private userId: string
  private userSig: string
  rtcCloud: TRTCCloud
  constructor(options: ConfigOption) {
    super()
    TRTCCloud.destroyTRTCShareInstance()

    this.appId = options.appId
    this.userId = options.userId
    this.userSig = options.userSig
    this.rtcCloud = TRTCCloud.getTRTCShareInstance()
    this.bindEvent()
  }

  private bindEvent() {
    this.rtcCloud.on('onEnterRoom', (result: number) => {
      this.emit(ENUM_EVENT.ENTER_ROOM_SUCCESS, { result: result })
    })
    this.rtcCloud.on('onExitRoom', (result: number) => {
      this.emit(ENUM_EVENT.LEAVE_ROOM_SUCCESS, { result: result })
    })
    this.rtcCloud.on('onRemoteUserEnterRoom', (uid: string) => {
      // console.log(TAG_NAME, 'teacherUserid', this.teacherUserID)
      // if (uid === this.teacherUserID) {
      this.emit(ENUM_EVENT.TEACHER_ENTER, { userID: uid })
      // } else {
      //   this.emit(ENUM_EVENT.STUDENT_ENTER, { userID: uid })
      // }
    })
    this.rtcCloud.on('onRemoteUserLeaveRoom', (uid: string) => {
      // console.log(TAG_NAME, 'teacherUserid', this.teacherUserID)
      // if (uid === this.teacherUserID) {
      this.emit(ENUM_EVENT.TEACHER_LEAVE, { userID: uid })
      // } else {
      //   this.emit(ENUM_EVENT.STUDENT_LEAVE, { userID: uid })
      // }
    })
    this.rtcCloud.on('onUserSubStreamAvailable', (uid: string, available: boolean) => {
      if (available) {
        this.emit(ENUM_EVENT.SCREEN_SHARE_ADD, { userID: uid })
      } else {
        this.emit(ENUM_EVENT.SCREEN_SHARE_REMOVE, { userID: uid })
      }
    })
    this.rtcCloud.on('onUserVideoAvailable', (uid: string, available: boolean) => {
      if (available) {
        this.emit(ENUM_EVENT.REMOTE_VIDEO_ADD, { userID: uid })
      } else {
        this.emit(ENUM_EVENT.REMOTE_VIDEO_REMOVE, { userID: uid })
      }
    })
    this.rtcCloud.on('onUserAudioAvailable', (uid: string, available: boolean) => {
      if (available) {
        this.emit(ENUM_EVENT.REMOTE_AUDIO_ADD, { userID: uid })
      } else {
        this.emit(ENUM_EVENT.REMOTE_AUDIO_REMOVE, { userID: uid })
      }
    })
    this.rtcCloud.on('onError', (errcode: number, errmsg: string) => {
      this.emit(ENUM_EVENT.ERROR, { errcode: errcode, errmsg: errmsg })
    })
    this.rtcCloud.on('onWarning', (warningCode: number, warningMsg: string) => {
      this.emit(ENUM_EVENT.WARNING, { errcode: warningCode, errmsg: warningMsg })
    })
    // this.tim.off(TIM.ENUM_EVENT.ERROR, this._onError)
    // this.tim.on(TIM.ENUM_EVENT.ERROR, this._onError.bind(this))
    // this.tim.off(TIM.ENUM_EVENT.MESSAGE_RECEIVED, this._onIMMessageReceived)
    // this.tim.on(TIM.ENUM_EVENT.MESSAGE_RECEIVED, this._onIMMessageReceived.bind(this))
    // this.tim.off(TIM.ENUM_EVENT.KICKED_OUT, this._onKickedOut)
    // this.tim.on(TIM.ENUM_EVENT.KICKED_OUT, this._onKickedOut.bind(this))
  }

  /**
   * @NOTE
   * 进入房间
   */
  public async enterRoom(roomOption: EnterRoomParams) {
    const param = new TRTCParams()
    param.sdkAppId = this.appId
    param.roomId = roomOption.classId
    param.userId = this.userId
    param.userSig = this.userSig
    param.streamId = '138822_78e0f17a4a83746aeb565e2fb755346c' // TODO:
    param.privateMapKey = ''
    param.businessInfo = ''
    /** 主播，可以上行视频和音频 */
    param.role = TRTCRoleType.TRTCRoleAnchor
    /** 视频通话场景，支持720P、1080P高清画质 */
    this.rtcCloud.enterRoom(param, TRTCAppScene.TRTCAppSceneLIVE)
  }

  /**
   * 获取房间详细资料
   * @params CreateRoomParams
   */
  getGroupProfile(classId: number) {
    // TODO:
  }

  /**
   * 进入教室自动创建房间
   * @老师创建教室
   * 初始化 IM连接 设置老师个人资料信息 TODO:
   * @params CreateRoomParams
   * 废弃
   */
  // createRoom(params: CreateRoomParams) {}

  /**
   * 根据教室id获取成员列表
   * @param {*} params
   * classId: number; // 教室id
   */
  // getMemberList(classId: number) {}

  /**
   * 老师开始问答时间
   * 逻辑：老师端广播通知，开始问答时间
   * 信令：{cmd: 1}
   * @params classId:number //教室id
   */
  // startQuestionTime(classId: number) {
  //   const params = {
  //     cmd: 1
  //   }
  //   return this.sendGroupCustomMessage(classId, JSON.stringify(params))
  // }

  /**
   * 停止问答时间
   * 逻辑：
   * - 老师主动停止问答时间
   * - 学生端收到停止回答时间的通知，已连麦的学生要停止连麦，关闭举手功能
   * 信令：{cmd: 5}
   * @params classId:number //教室id
   */
  // stopQuestionTime(classId: number) {
  //   const params = {
  //     cmd: 5
  //   }
  //   return this.sendGroupCustomMessage(classId, JSON.stringify(params))
  // }

  /**
   * 老师邀请学生上台回答
   * 逻辑：
   * - 选择举手列表里的学生 userID ，发送邀请通知
   * - 学生端收到邀请上台回答事件，受邀请的学生开麦
   * or
   * - 如果没有学生举手
   * - 直接点名回答，学生端收到邀请上台回答事件，被点名的学生开麦
   * 信令: {cmd: 3}
   * @params userID:string //用户id
   */
  inviteToPlatform(userID: string) {
    const params = {
      cmd: 3
    }
    return this.sendCustomMessage(userID, JSON.stringify(params))
  }

  /**
   * 学生举手
   * 逻辑：
   * - 学生发送举手通知
   * - 老师端收到学生举手通知
   * 状态：
   * - 问答时间开始
   */
  // raiseHand() {
  //   const params = {
  //     cmd: 2,
  //     nickName: this.nickName
  //   }
  //   if (this.teacherUserID) {
  //     return this.sendCustomMessage(this.teacherUserID, JSON.stringify(params))
  //   }
  // }
  /**
   * 结束回答
   * 逻辑：
   * - 老师结束学生回答
   * - 学生收到结束回答的通知，指定的学生停止连麦
   * 信令: {cmd: 4}
   * @params userID:string //用户id
   */
  finishAnswering(userID: string) {
    const params = {
      cmd: 4
    }
    return this.sendCustomMessage(userID, JSON.stringify(params))
  }

  /**
   * @打开摄像头
   * @param view 显示摄像头信息
   * @param resolution 分辨率
   */
  openCamera(view: HTMLElement, resolution?: TRTCVideoResolution) {
    const encParam = new TRTCVideoEncParam()
    encParam.videoResolution = resolution || TRTCVideoResolution.TRTCVideoResolution_480_480
    this.rtcCloud.setVideoEncoderParam(encParam)
    this.rtcCloud.startLocalPreview(view)
  }

  /** @关闭摄像头 */
  closeCamera() {
    this.rtcCloud.stopLocalPreview()
  }

  /** @获取摄像头列表 */
  getCameraList() {
    return this.rtcCloud.getCameraDevicesList()
  }

  /**
   * @设置摄像头
   * @params deviceId:string //从 getCameraDevicesList 中得到的设备 ID
   */
  setCurrentCamera(deviceId: string) {
    this.rtcCloud.setCurrentCameraDevice(deviceId)
  }

  /** @NOTE {开启本地音频的采集和上行} */
  openMicrophone() {
    this.rtcCloud.startLocalAudio()
    this.rtcCloud.muteLocalAudio(false)
    // console.log(`-----声音正常`, this.rtcCloud.getAudioCaptureVolume()) 获取音量
  }

  /** @NOTE {关闭本地音频的采集和上行} */
  closeMicrophone() {
    this.rtcCloud.stopLocalAudio()
    this.rtcCloud.muteLocalAudio(true)
  }

  /** @获取麦克风设备列表 */
  getMicrophoneList() {
    return this.rtcCloud.getMicDevicesList()
  }

  /**
   * @设置麦克风
   * @params micId:string //从 getMicDevicesList 中得到的设备 ID
   */
  setCurrentMicDevice(micId: string) {
    this.rtcCloud.setCurrentMicDevice(micId)
  }

  /*
   * 发送自定义消息
   * @params
   * userID:string //消息接收方的 userID
   * data:string //自定义消息的数据字段
   */
  sendCustomMessage(userID: string, data: string) {}

  private clearData() {
    /** 关闭麦克风 */
    this.closeMicrophone()
    /** 关闭摄像头 */
    this.rtcCloud.stopLocalPreview()
    /** 关闭屏幕分享 */
    this.rtcCloud.stopScreenCapture()
  }
  /**
   * 逻辑：
   * 老师-退出trtc房间
   * 学生-退出群组、退出 trtc 房间
   * @params role,classId
   */
  exitRoom() {
    this.clearData()
    this.rtcCloud.exitRoom()
  }

  /**
   * 设置系统当前麦克风设备的音量
   * @params
   * volume: number; 音量数值0-100
   */
  setCurrentMicDeviceVolume(volume: number) {
    this.rtcCloud.setCurrentMicDeviceVolume(volume)
  }

  /**
   * 发送聊天室消息
   * @params MessageParams
   */
  sendTextMessage(params: MessageParams) {}

  /**
   * 获取屏幕分享窗口列表
   */
  getScreenShareList(): ScreenShareType[] {
    return this.rtcCloud.getScreenCaptureSources(120, 70, 20, 20)
  }

  /**
   * @选择屏幕，开始推流
   * @params SourceParam
   */
  startScreenCapture(source: SourceParam, view?: HTMLElement | null) {
    const rect = new Rect(0, 0, 0, 0)
    const mouse = true
    const highlight = true
    this.rtcCloud.selectScreenCaptureTarget(source.type, source.sourceId, source.sourceName, rect, mouse, highlight)
    this.rtcCloud.startScreenCapture(view)
  }

  /*
   * 关闭屏幕分享推流
   */
  stopScreenCapture() {
    this.rtcCloud.stopScreenCapture()
  }

  //开启大小画面双路编码模式
  openSmallVideoStream() {
    // const param = new TRTCVideoEncParam()
    // param.videoFps = 15
    // param.videoBitrate = 100
    // param.videoResolution = TRTCVideoResolution.TRTCVideoResolution_320_240
    // param.resMode = TRTCVideoResolutionMode.TRTCVideoResolutionModeLandscape
    // this.rtcCloud.enableSmallVideoStream(true, param)
  }

  //开启大小画面双路编码模式
  closeSmallVideoStream() {
    // const param = new TRTCVideoEncParam()
    // param.videoFps = 15
    // param.videoBitrate = 100
    // param.videoResolution = TRTCVideoResolution.TRTCVideoResolution_320_240
    // param.resMode = TRTCVideoResolutionMode.TRTCVideoResolutionModeLandscape
    // this.rtcCloud.enableSmallVideoStream(false, param)
  }

  /*
   * 开始显示远端视频画面或屏幕分享画面
   * @params RemoteParams
   */
  // startRemoteView(params: RemoteParams) {
  //   if (params.streamType === 1) {
  //     this.rtcCloud.startRemoteView(params.userID, params.view, TRTCVideoStreamType.TRTCVideoStreamTypeBig)
  //   } else if (params.streamType === 2) {
  //     this.rtcCloud.startRemoteView(params.userID, params.view, TRTCVideoStreamType.TRTCVideoStreamTypeSmall)
  //   } else if (params.streamType === 3) {
  //     this.rtcCloud.startRemoteView(params.userID, params.view, TRTCVideoStreamType.TRTCVideoStreamTypeSub)
  //   }
  // }

  /*
   * 停止显示远端视频画面或屏幕分享画面，同时不再拉取该远端用户的数据流
   * @params StopRemoteParams
   */
  // stopRemoteView(params: StopRemoteParams) {
  //   if (params.streamType === 1) {
  //     this.rtcCloud.stopRemoteView(params.userID, TRTCVideoStreamType.TRTCVideoStreamTypeBig)
  //   } else if (params.streamType === 2) {
  //     this.rtcCloud.stopRemoteView(params.userID, TRTCVideoStreamType.TRTCVideoStreamTypeSmall)
  //   } else if (params.streamType === 3) {
  //     this.rtcCloud.stopRemoteView(params.userID, TRTCVideoStreamType.TRTCVideoStreamTypeSub)
  //   }
  // }

  /*
   * 设置美颜、美白、红润效果级别
   * @params BeautyParams
   */
  setBeautyStyle(params: BeautyParams) {
    if (params.beautyStyle === 1) {
      this.rtcCloud.setBeautyStyle(TRTCBeautyStyle.TRTCBeautyStyleSmooth, params.beauty, params.white, params.ruddiness)
    } else {
      this.rtcCloud.setBeautyStyle(TRTCBeautyStyle.TRTCBeautyStyleNature, params.beauty, params.white, params.ruddiness)
    }
  }
}
